package com.woniu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.entity.SysLoginLog;
import com.woniu.mapper.SysLoginLogMapper;
import com.woniu.service.SysLoginLogService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Collection;
import java.util.List;

/**
 * @Author pml
 * @Date 2025/6/18 23:05
 * @Description TODO
 * 登录日志服务实现类
 * 使用响应式编程包装阻塞的数据库操作
 */
@Service
public class SysLoginLogServiceImpl extends ServiceImpl<SysLoginLogMapper, SysLoginLog> implements SysLoginLogService {

    @Resource
    private SysLoginLogMapper sysLoginLogMapper;

    /**
     * 响应式保存登录日志
     * 使用Mono.fromCallable将阻塞操作包装为异步
     * 并指定在boundedElastic调度器上执行，避免阻塞Netty事件循环
     */
    @Override
    public Mono<Boolean> saveLoginLog(SysLoginLog loginLog) {
        return Mono.fromCallable(() -> save(loginLog))
                .subscribeOn(Schedulers.boundedElastic());
    }

    /**
     * 批量查询登录日志
     * 直接调用父类方法，保持代码一致性
     * @param logIds 日志ID集合
     * @return 日志列表
     */
    @Override
    public List<SysLoginLog> listByIds(Collection<? extends Serializable> logIds) {
        return super.listByIds(logIds);
    }

    /**
     * 根据用户ID查询登录日志
     * 使用QueryWrapper构建查询条件，按登录时间倒序排列，便于查看最新登录记录
     * @param userId 用户ID
     * @return 该用户的登录日志列表
     */
    @Override
    public List<SysLoginLog> listByUserId(Integer userId) {
        QueryWrapper<SysLoginLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                .orderByDesc("login_time"); // 最新登录记录排在前面
        return sysLoginLogMapper.selectList(queryWrapper);
    }

    /**
     * 清理过期日志
     * 计算过期时间点，删除该时间点之前的所有日志
     * 使用QueryWrapper构建条件，提高代码可读性
     * @param days 保留最近天数
     * @return 清理的记录数
     */
    @Override
    public int cleanExpiredLogs(int days) {
        LocalDateTime expiredTime = LocalDateTime.now().minus(days, ChronoUnit.DAYS);
        QueryWrapper<SysLoginLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("login_time", expiredTime);
        return sysLoginLogMapper.delete(queryWrapper);
    }
}
